package com.ruoyi.system.service.impl;

import java.net.InetAddress;
import java.net.Socket;
import java.util.List;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.NetInfoLogMapper;
import com.ruoyi.system.domain.NetInfoLog;
import com.ruoyi.system.service.INetInfoLogService;
import com.ruoyi.common.core.text.Convert;

/**
 * 网络连接记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-09-17
 */
@Service
public class NetInfoLogServiceImpl implements INetInfoLogService 
{
    @Autowired
    private NetInfoLogMapper netInfoLogMapper;

    /**
     * 查询网络连接记录
     * 
     * @param logId 网络连接记录主键
     * @return 网络连接记录
     */
    @Override
    public NetInfoLog selectNetInfoLogByLogId(Long logId)
    {
        return netInfoLogMapper.selectNetInfoLogByLogId(logId);
    }

    /**
     * 查询网络连接记录列表
     * 
     * @param netInfoLog 网络连接记录
     * @return 网络连接记录
     */
    @Override
    public List<NetInfoLog> selectNetInfoLogList(NetInfoLog netInfoLog)
    {
        return netInfoLogMapper.selectNetInfoLogList(netInfoLog);
    }

    /**
     * 新增网络连接记录
     * 
     * @param netInfoLog 网络连接记录
     * @return 结果
     */
    @Override
    public int insertNetInfoLog(NetInfoLog netInfoLog)
    {

        // 设置连接时间为当前时间
        netInfoLog.setConnectTime(DateUtils.getNowDate());

        // 根据是否有端口号来决定测试类型
        if (netInfoLog.getPort() != null && netInfoLog.getPort() > 0) {
            // 有端口号，进行端口可达性测试
            netInfoLog.setType(1); // IP与端口可达性测试
            boolean isReachable = testIpAndPort(netInfoLog.getIp(), netInfoLog.getPort().intValue());
            netInfoLog.setResult(isReachable ? 1 : 0); // 1表示成功，0表示失败
        } else {
            // 无端口号，只进行IP可达性测试
            netInfoLog.setType(0); // IP可达性测试
            boolean isReachable = testIpOnly(netInfoLog.getIp());
            netInfoLog.setResult(isReachable ? 1 : 0); // 1表示成功，0表示失败
        }


        // 查询前置条件 只能查当前用户的信息
        SysUser currentUser = ShiroUtils.getSysUser();
        netInfoLog.setUserId(currentUser.getUserId());
        netInfoLog.setDeptId(currentUser.getDeptId());

        netInfoLog.setCreateTime(DateUtils.getNowDate());
        return netInfoLogMapper.insertNetInfoLog(netInfoLog);
    }

    /**
     * 修改网络连接记录
     * 
     * @param netInfoLog 网络连接记录
     * @return 结果
     */
    @Override
    public int updateNetInfoLog(NetInfoLog netInfoLog)
    {
        netInfoLog.setUpdateTime(DateUtils.getNowDate());
        return netInfoLogMapper.updateNetInfoLog(netInfoLog);
    }

    /**
     * 批量删除网络连接记录
     * 
     * @param logIds 需要删除的网络连接记录主键
     * @return 结果
     */
    @Override
    public int deleteNetInfoLogByLogIds(String logIds)
    {
        return netInfoLogMapper.deleteNetInfoLogByLogIds(Convert.toStrArray(logIds));
    }

    /**
     * 删除网络连接记录信息
     * 
     * @param logId 网络连接记录主键
     * @return 结果
     */
    @Override
    public int deleteNetInfoLogByLogId(Long logId)
    {
        return netInfoLogMapper.deleteNetInfoLogByLogId(logId);
    }

    /**
     * 测试IP是否可达（仅测试IP）
     *
     * @param ip IP地址
     * @return 是否可达
     */
    private boolean testIpOnly(String ip) {
        try {
            InetAddress address = InetAddress.getByName(ip);
            return address.isReachable(1000); // 1秒超时
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 测试IP和端口是否可达
     *
     * @param ip IP地址
     * @param port 端口号
     * @return 是否可达
     */
    private boolean testIpAndPort(String ip, int port) {
        try {
            // 先测试IP是否可达
            InetAddress address = InetAddress.getByName(ip);
            if (!address.isReachable(1000)) {
                return false;
            }

            // 再测试端口是否开放
            Socket socket = new Socket();
            socket.connect(new java.net.InetSocketAddress(ip, port), 1000); // 1秒超时
            socket.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
